var express = require('express'),
	utils = require('./lib/utils'),
	passwordHash = require('password-hash'),
	ENV = process.env.NODE_ENV || 'development',
	http = require('http'),
	path = require('path'),
	expressLayouts = require('express-ejs-layouts'),
	cons = require('consolidate'),
	fs = require('fs');


global.app = express();
var controllerDir = __dirname + '/core/controllers/';

utils.loadConfig(__dirname + '/config', function(config) {

	app.configure(function(){
		app.set('port', config[ENV].PORT);
		
		// assign the swig engine to .html files
		app.engine('html', cons.ejs);

		// set .html as the default extension 
		app.set('view engine', 'html');
		app.set('views', __dirname + '/views');
		app.set('layout', 'layout/connected');
		
		app.use(expressLayouts);
		app.use(express.favicon());
		app.use(express.bodyParser());
		app.use(express.methodOverride());
		app.use(express.cookieParser('your secret here'));
		app.use(express.session());
		app.use(express.static(path.join(__dirname,'public')));
	});

	app.configure('development', function(){
		app.use(express.errorHandler());
		app.use(express.logger('dev'));
		config.db[ENV].logging = console.log;
	});
	
	app.configure('production', function(){
		app.use(gzippo.compress());
		config.db[ENV].logging = false;
		app.use(connectTimeout({
			time : parseInt(config[ENV].REQ_TIMEOUT, 10)
		}));
	});
	
	global.db = require("./core/database")(config.db[ENV]);
	var models = require('./core/Models');
	
	
	// Session-persisted message middleware
	app.use(function(req, res, next){
		var err = req.session.error
			, msg = req.session.success;
		delete req.session.error;
		delete req.session.success;
		res.locals.message = '';
		if (err) res.locals.message = '<div class="alert alert-error"><button type="button" class="close" data-dismiss="alert">×</button>' + err + '</div>';
		if (msg) res.locals.message = '<div class="alert alert-success"><button type="button" class="close" data-dismiss="alert">×</button>' + msg + '</div>';
		res.locals.baseurl = config.site_url;
		next();
	});
	
	app.use(function(req, res, next){
		if (req.session.user) {
			cons.ejs(__dirname + '/views/header.html', {}, function(err, html) {
				if (err) throw err;
				res.locals.nav = html;
			});
		}
		next();
	});
	
	function authenticate(name, pass, fn) {
		if (!module.parent) console.log('authenticating %s:%s', name, pass);
		models.get('User').find({ where: {login: name} }).success(function(user) {
			if (!user) return fn(new Error('cannot find user'));
			if (passwordHash.verify(pass, user.password)) {
				return fn(null, user);
			} else {
				fn(new Error('invalid password'));
			}
		}).error(function(error) {
			console.log('error : ' + error);
			return fn(new Error('cannot find user'));
		});
	}
	
	app.get('/', function(req, res){
		res.redirect('login');
	});

	app.get('/logout', function(req, res){
		req.session.destroy(function(){
			res.redirect('/');
		});
	});

	app.get('/login', function(req, res){
		if (req.session.user) {
			res.redirect('/home');
		}
		res.render('login', {layout: 'layout/notConnected'});
	});

	app.post('/login', function(req, res){
		authenticate(req.body.username, req.body.password, function(err, user){
			if (user) {
				// Regenerate session when signing in
				// to prevent fixation
				req.session.regenerate(function(){
					// Store the user's primary key
					// in the session store to be retrieved,
					// or in this case the entire user object
					req.session.user = user;
					res.redirect('home');
				});
			} else {
				req.session.error = 'Authentication failed, please check your '
					+ ' username and password.'
					+ ' (use "tj" and "foobar")';
				res.redirect('login');
			}
		});
	});
	
	 fs.readdir(controllerDir, function(err, list) {
		if (!list) return;
		list.forEach(function(file) {
			var filePath = controllerDir + file.split('/').pop().replace('.js', '');
			require(filePath)();
		});
	 });

	

	if (!module.parent) {
		http.createServer(app).listen(app.get('port'), function(){
			console.log("Express server listening on port " + app.get('port'));
		});
	}
});